package com.example.common;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;

public abstract class ConcurrentHarness {

	protected static final int CYCLES = 1000000;
	protected ExecutorService executor;

	@Before
	public void initExecutor() {
		executor = Executors.newFixedThreadPool(4);
	}

	@After
	public void waitAllTasks() throws InterruptedException {
		executor.shutdown();
		boolean terminated = executor.awaitTermination(10, TimeUnit.SECONDS);

		assertTrue("Finished all tasks", terminated);
		checkResults();
	}

	abstract protected void checkResults();

	abstract protected Runnable newTask();

	protected void submitTasks() {
		try {
			for (int i = 0; i < CYCLES; i++) {
				executor.submit(newTask());
			}
		} catch (RejectedExecutionException e) {
			fail("Execution rejected");
		}
	}

}